﻿using System;
using System.Collections.Generic;
using AgencyEntityLib.BaseEntity;

using FormControllers;
using Ecopsy.Tools;
using System.Web.UI.WebControls;
using SqlLibrary;
using Ecopsy.DataTier;
using AgencyEntityLib.Context;

public class TaskCalendar
{
    public enum CalendarPeriod { Day, Week, Month } ;

    private string key = "CalendarWhere";


    public  ListWhere Where
    {
        get
        {
            ListWhere r = null;
            if (!CacheTools.IsCacheObject(key))
            {
                r = new ListWhere();
                r.ListLoadStatment = new TaskList.sqlLoadStatment();
                r.SortCondition.SortDirection = SortDirection.Ascending;
                r.SortCondition.SortField = "s_TaskContent";
                CacheTools.SetCacheObject(key, r);
            }
            return (ListWhere)CacheTools.GetCacheObect(key);
        }
        set
        {
            CacheTools.ResetCache(key);
            CacheTools.SetCacheObject(key, value);
        }

    }

    //public WhereCondition Where
    //{
    //    get
    //    {

    //        if (!CacheTools.IsCacheObject(key))
    //        {
    //            WhereCondition r = new WhereCondition();
    //            XmlWhere MatchValue = new XmlWhere();
    //            r.Match = MatchValue;
    //            r.SortCondition.SortField = "s_TaskContent";
    //            CacheTools.SetCacheObject(key, r);
    //        }
    //        return (WhereCondition)CacheTools.GetCacheObect(key);
    //    }
    //    set
    //    {
    //        CacheTools.ResetCache(key);
    //        CacheTools.SetCacheObject(key, value);
    //    }

    //}

    protected TaskList GetList(DateTime st, DateTime fn)
    {
         wsTask w = (wsTask)AgencyLib_GlobalConstants.CurrentAgency.WS_FactoryList[WS_FactoryList.wsKey_Task];
        ((TaskList.sqlLoadStatment)Where.ListLoadStatment).dtStart = st;
        ((TaskList.sqlLoadStatment)Where.ListLoadStatment).dtFinish = fn;
        TaskList tList = w.GetTaskList((TaskList.sqlLoadStatment) Where.ListLoadStatment);
        return tList;
    }

    public class Term
    {
        
        public Term(DateTime value,TimeSpan span)
        {
            _Timespan = span;
            _DtStart = DateTimeTools.ResetTime (value);
        }
        private DateTime _DtStart = DateTime.Now;
        private TimeSpan _Timespan = new TimeSpan(1, 0, 0);

        public string ToTxt(Func<DateTime, TimeSpan, string> FormatFunction)
        {
            return FormatFunction(_DtStart, _Timespan);  
        }

        public string ToTxtTime(Func<DateTime,  string> FormatFunction)
        {
            return FormatFunction(_DtStart );
        }


        public DateTime GetDateForNewTask(Func<DateTime, TimeSpan, DateTime> DateTimeSource)
        {
            return DateTimeSource(_DtStart, _Timespan);
        }

                
        
    }

    public static TaskCalendar GetCalendar(DateTime Day, CalendarPeriod CalendarPeriod)
    {
        switch (CalendarPeriod)
        { 
            case  CalendarPeriod.Week  :
                return new TaskCalendar_Week(Day, CalendarPeriod);
        }

        return new TaskCalendar_Day(Day, CalendarPeriod);
    }
       

    public   DateTime _Day = DateTime.Now;
    public DateTime _LastDay = DateTime.Now;    
    


    protected  CalendarPeriod _CalendarPeriod = CalendarPeriod.Day;
    
    public  TaskCalendar(DateTime Day, CalendarPeriod CalendarPeriod)
    {
        //if (this is TaskCalendar_Day) return CalendarPeriod.Day;
        //if (this is TaskCalendar_Week) return CalendarPeriod.Week ;
        //return CalendarPeriod.Month;
    }

    public virtual string GetPeriodAsText 
    {
        get { return _Day.ToShortDateString() + "-" + _LastDay.ToShortDateString();   }
    }
 


    protected virtual void LoadItems()
    {
    }

    private bool LoadWeek()
    {       
        return true;
    }

    protected  List<grdCalendarRow> _Items = new List<grdCalendarRow>();
    
    public    List<grdCalendarRow>Items
    {
        get 
        {
            _Items.Clear();
            LoadItems();
            return _Items;
        } 
    }

    protected class RowSorter : IComparer<grdCalendarRow>
    {

        #region IComparer<grdCalendarRow> Members

        public int Compare(grdCalendarRow x, grdCalendarRow y)
        {            
            return x.dtFinish.CompareTo(y.dtFinish );
        }

        #endregion
    }

    public virtual DateTime  AddTerm()
    {
        return DateTime.MinValue  ;
    }
    public virtual  DateTime MinusTerm()
    {
        return DateTime.MinValue  ;
    }


}

public class grdCalendarRow : grdTask
{
    public grdCalendarRow(Task t) : base(t) { }
    
    public  TaskCalendar.Term Term { get; set; }

    public virtual  DateTime DateForNewTask 
    {
        get { return Term.GetDateForNewTask(null); }
    }

    public virtual bool ToggleEnabled { get { return false; } }
    
    public grdTask grdTack { get; set; }
    public bool iHaveTask { get { return (_Task == null); } }
    //public virtual string TaskContent { get { return (_Task == null ? "&nbsp" : _Task.TaskContent); } }
    public override string  s_TaskContent
{
	get 
	{ 
		 return (_Task == null ? "&nbsp" : _Task.TaskContent);  
	}
}
    public override string s_Client
    {
        get
        {

            return (_Task == null ? "&nbsp" : base.s_Client);
        }
    }
    public string TaskId { get { return (_Task == null ? "&nbsp" : _Task.ID); } }
    public override string s_Closed
    {
        get { return (_Task == null ? "&nbsp" : base.s_Closed); }
    }

    public virtual string txtTerm
    {
        get
        {
            return string.Empty;
        }
    }

    public virtual string txtTermTime
    {
        get
        {
            return "&nbsp";
        }
    }

    public override string s_Type
    {
        get
        {
            return (_Task == null ? "&nbsp" : base.s_Type);

        }
    }
    
    public bool IsClosed
    {
        get
        {
            return (_Task == null ? false : _Task.IsClosed);
        }
    }

    


}


public class TaskCalendar_Day : TaskCalendar
{
    public TaskCalendar_Day(DateTime Day, CalendarPeriod CalendarPeriod) : base(Day, CalendarPeriod) 
    {
        _Day = DateTimeTools.ResetTime(Day);
        _LastDay = _Day;
        _CalendarPeriod = CalendarPeriod;
    }
        
    protected override void  LoadItems()
    {
        TaskList tList = GetList(DateTimeTools.ResetTime(_Day), DateTimeTools.AroundDay(_LastDay));        
        int CurrentH = 0;
        

        //  функция  вычисляющая условие включени задачи 
        Func<Task, bool> Fetch_Where = delegate(Task t)
        {
            if (DateTimeTools.ResetTime(t.dtFinish) == DateTimeTools.ResetTime(_Day))
                if (t.dtFinish .Hour == CurrentH) return true;
            return false;
        };
        
        _Items.Clear(); 
        for ( int i=8; i < 21; i++)
        {
            CurrentH = i;
          //  List<Task> r = tList.DayFetch(_Day, i);
            List<Task> r = tList.Fetch(Fetch_Where);
            if (r.Count > 0)
            {
                foreach (Task item in r)
                {
                    _Items.Add(new grdCalendarRow_Day(item) { Term = new Term (item.dtFinish,new TimeSpan (i,0,0)) });
                }
            }
            else
            {
                _Items.Add(new grdCalendarRow_Day(null) { Term = new Term(_Day, new TimeSpan(i, 0, 0)) });
            }

        }
        
    }

    public override DateTime AddTerm()
    {
        return _Day.AddDays(1);
    }
    
    public  override DateTime MinusTerm()
    {
         return _Day.AddDays(-1);
    }

    public override string GetPeriodAsText
    {
        get
        {
            return _Day.ToShortDateString () ;
        }
    }

}

public class grdCalendarRow_Day : grdCalendarRow
{
    public grdCalendarRow_Day(Task t) : base(t) { }

    public override DateTime DateForNewTask
    {
        get
        {
            Func<DateTime, TimeSpan, DateTime > r = delegate(DateTime _dtStart, TimeSpan _Term)
            {
                return DateTimeTools.ResetTime(_dtStart).Add(_Term);
            };

            return Term.GetDateForNewTask(r);     
        }
    }

    public override string txtTerm
    {
        get
        {
            Func<DateTime, TimeSpan, string> r = delegate(DateTime _dtStart, TimeSpan _Term) 
            { 
                return _dtStart.Add(_Term).Hour.ToString()+":00"   ; 
            };
            return Term.ToTxt(r);
        }
    }

   

}

public class TaskCalendar_Week : TaskCalendar
{
    public TaskCalendar_Week(DateTime Day, CalendarPeriod CalendarPeriod)
        : base(Day, CalendarPeriod)
    {

        _Day = DateTimeTools.GetFisrtDayInWeek (Day);
        _LastDay=_Day.AddDays(7); 
        _CalendarPeriod = CalendarPeriod;
        
    }

    protected override void LoadItems()
    {

        int CurrentDay = 0;

        TaskList tList = GetList(DateTimeTools.ResetTime(_Day), DateTimeTools.AroundDay(_LastDay));
        


        //  функция  вычисляющая условие включени задачи 
        Func<Task, bool> Fetch_Where = delegate(Task t)
        {
            if (DateTimeTools.ResetTime(t.dtFinish) == DateTimeTools.ResetTime(_Day.AddDays(CurrentDay))) return true;
            return false;
        };

        Func<Task, Task, int> _ComareFunc = delegate(Task x, Task y) 
        {
            return (x.dtFinish.Hour - y.dtFinish.Hour);   
            
        };
        
        _Items.Clear();
        for (int i = 0; i < 7; i++)
        {
            CurrentDay = i;
            // список задач на этот день
            List<Task> r = tList.Fetch(Fetch_Where);
            // задачи по часам
            r.Sort(new CalendarTaskComparer(_ComareFunc));
            if (r.Count > 0)
            {
                foreach (Task item in r)
                {
                    _Items.Add(new grdCalendarRow_Week(item) {  Term = new Term(_Day.AddDays(i), new TimeSpan(1, 0, 0, 0)) });
                }
            }
            else
            {
                _Items.Add(new grdCalendarRow_Week(null) { Term = new Term(_Day.AddDays(i), new TimeSpan(1, 0, 0, 0)) });
            }

        }

    }

    public override DateTime AddTerm()
    {
        return _LastDay;
    }

    public override DateTime MinusTerm()
    {
        return _LastDay.AddDays(+7);
    }

}

public class grdCalendarRow_Week : grdCalendarRow
{
    public grdCalendarRow_Week(Task t) : base(t) { }
    public override string txtTerm
    {
        get
        {
            Func<DateTime, TimeSpan, string> r = delegate(DateTime _dtStart, TimeSpan _Term) 
            {
                Dictionary<string, string> d = new Dictionary<string, string>();
                d.Add("monday", "пн.");
                d.Add("tuesday", "вт.");
                d.Add("wednesday", "ср.");
                d.Add("thursday", "чт.");
                d.Add("friday", "пт.");
                d.Add("saturday", "сб.");
                d.Add("sunday", "вс.");

                return d[_dtStart.DayOfWeek.ToString().ToLower()]+ " " + _dtStart.Day.ToString() + "." + _dtStart.Month.ToString(); 
            };
            return Term.ToTxt(r); 
        }
    }
    public override string txtTermTime
    {
        get
        {
            return (_Task == null ? "&nbsp" : _Task.dtFinish.Hour .ToString () +":00" );
        }
    }

    public override string s_TaskContent
    {
        get
        {
            return txtTermTime +" "+ base.s_TaskContent;
        }
    }

    public override DateTime DateForNewTask
    {
        get
        {
            Func<DateTime, TimeSpan, DateTime> r = delegate(DateTime _dtStart, TimeSpan _Term)
            {
                return DateTimeTools.ResetTime(_dtStart).AddHours(8);
            };

            return Term.GetDateForNewTask(r);
        }
    }

    public override bool ToggleEnabled
    {
        get
        {
            return true;
        }
    }

    
    
}

public class CalendarTaskComparer:IComparer <Task> 
{
    private Func <Task , Task , int> _ComareFunc;
    public CalendarTaskComparer(Func<Task, Task, int> ComareFunc)
    {
        _ComareFunc = ComareFunc;
    }
    #region IComparer<Task> Members

    public int Compare(Task x, Task y)
    {
        return _ComareFunc(x, y);
    }

    #endregion
}



